package com.itfreer.power.service.power;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.itfreer.power.PowerParameter;
import com.itfreer.power.dao.user.UserAuthenticationDao;
import com.itfreer.power.dao.user.UserRoleDao;
import com.itfreer.power.dao.user.VUserInfoDao;
import com.itfreer.power.entity.user.UserAuthenticationEntity;
import com.itfreer.power.entity.user.UserInfoEntity;
import com.itfreer.power.entity.user.UserRoleEntity;
import com.itfreer.power.entity.user.VUserInfoEntity;
import com.itfreer.power.entity.useredit.UserSysAuthoEntity;
import com.itfreer.power.service.power.strategy.DataJurisdictionDataProvide;
import com.itfreer.power.service.power.strategy.MapExtentJurisdictionDataProvide;
import com.itfreer.power.service.power.strategy.MapLayersJurisdictionDataProvide;
import com.itfreer.power.service.power.strategy.MenusJurisdictionDataProvide;
import com.itfreer.power.service.power.strategy.RoleDataDataProvide;
import com.itfreer.power.service.power.strategy.RoleDataProvide;
import com.itfreer.power.service.power.strategy.RoleEntrustDataProvide;
import com.itfreer.power.service.power.strategy.RoleMapExtentDataProvide;
import com.itfreer.power.service.power.strategy.RoleMapLayersDataProvide;
import com.itfreer.power.service.power.strategy.RoleMenusDataProvide;
import com.itfreer.power.service.power.strategy.RoleServiceDataProvide;
import com.itfreer.power.service.power.strategy.ServiceJurisdictionDataProvide;
import com.itfreer.power.service.role.RoleDataCache;
import com.itfreer.power.service.role.RoleService;
import com.itfreer.power.service.user.UserInfoService;
import com.itfreer.power.service.useredit.UserSysAuthoService;
import com.itfreer.power.utils.PasswordEncoder;

/**
 * 定义对外的综合服务接口
 */
@Component("powerService")
public class PowerServiceBase implements PowerService {

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 用户信息管理接口
	 */
	@Autowired
	private VUserInfoDao userInfoManage;

	@Autowired
	private UserInfoService userInfoService;

	@Autowired
	private UserRoleDao userRoleDao;

	@Autowired(required = false)
	private PowerParameter powerParameter;

	@Autowired(required = false)
	@Qualifier("superAdmin")
	private VUserInfoEntity superAdmin;

	@Autowired
	private UserAuthenticationDao userAuthenticationDao;

	@Autowired(required = false)
	private PasswordEncoder passwordEncoder;

	@Autowired(required = false)
	private RoleDataProvide roleDataProvide;

	@Autowired(required = false)
	private RoleEntrustDataProvide roleEntrustDataProvide;

	@Autowired(required = false)
	private RoleServiceDataProvide roleServiceDataProvide;

	@Autowired(required = false)
	private ServiceJurisdictionDataProvide serviceJurisdictionDataProvide;

	@Autowired(required = false)
	private RoleMenusDataProvide roleMenusDataProvide;

	@Autowired(required = false)
	private MenusJurisdictionDataProvide menusJurisdictionDataProvide;

	@Autowired(required = false)
	private RoleDataDataProvide roleDataDataProvide;

	@Autowired(required = false)
	private DataJurisdictionDataProvide dataJurisdictionDataProvide;

	@Autowired(required = false)
	private RoleMapLayersDataProvide roleMapLayersDataProvide;

	@Autowired(required = false)
	private MapLayersJurisdictionDataProvide mapLayersJurisdictionDataProvide;

	@Autowired(required = false)
	private RoleMapExtentDataProvide roleMapExtentDataProvide;

	@Autowired(required = false)
	private MapExtentJurisdictionDataProvide mapExtentJurisdictionDataProvide;

	@Autowired(required = false)
	private UserSysAuthoService userSysAuthoService;
	/**
	 * 角色数据缓存
	 */
	@Autowired(required = false)
	private RoleDataCache roleDataCache;
	@Autowired
	private RoleService roleService;

	/**
	 * 获取用户
	 * 
	 * @param userid
	 *            唯一值
	 * @return
	 */
	public VUserInfoEntity getUser(String userid, String userName) {
		VUserInfoEntity entity = null;
		if (userid != null && !userid.trim().equals("")) {
			entity = userInfoManage.getEntity(userid);
			if (entity != null) {
				logger.debug("从数据库中获取到用户。");
				if (powerParameter != null && powerParameter.isAllUserIsSuperAdmin()) {
					entity.setIsSuperAdmin(true);
					logger.debug("已将当前用户设置为超级管理员。");
				} else {
					logger.debug("未能将当前用户设置为超级管理员，未配置。");
				}
			} else {
				logger.debug("未能从数据库中获取到用户，userid在数据库中不存在。");
			}
		} else {
			logger.debug("未能从数据库中获取到用户，userid为空。");
		}

		if (entity != null) {
			return entity;
		}

		if (superAdmin == null || powerParameter == null || !powerParameter.getSupportSuperAdmin()) {
			logger.debug("未能从超级管理员中获取到用户，原因：");
			if (superAdmin == null) {
				logger.debug("超级管理员为null。");
			}
			if (powerParameter == null) {
				logger.debug("PowerParameter为null。");
			} else {
				logger.debug("getSupportSuperAdmin为false。");
			}
			return null;
		}

		if (superAdmin.getUserid().equals(userName)) {
			entity = superAdmin;
			entity.setIsSuperAdmin(true);
			logger.debug("从超级管理员中获得用户。");
			return entity;
		} else {
			logger.debug("未能从超级管理员中获取到用户，当前用户【" + userName + "】，超级管理员用户【" + superAdmin.getUserid() + "】。");
			return null;
		}
	}

	/**
	 * 通过帐号注册
	 * 
	 * @param accounts
	 * @param password
	 * @param rPassword
	 */
	public boolean userRegister(String accounts, String password, String rPassword) {
		if (accounts == null || accounts.equals("") || password == null || password.equals("") || rPassword == null
				|| rPassword.equals("")) {
			return false;
		}

		if (!password.equals(rPassword)) {
			return false;
		}

		if (passwordEncoder != null) {
			password = passwordEncoder.encode(password);
		}

		String userId = UUID.randomUUID().toString().replace("-", "");
		// 添加登录信息
		UserAuthenticationEntity entity = new UserAuthenticationEntity();
		entity.setUserid(userId);
		entity.setAccounts(accounts);
		entity.setPassword(password);
		entity.setValid(true);
		userAuthenticationDao.add(entity);

		// 添加用户信息
		UserInfoEntity user = new UserInfoEntity();
		user.setUserid(userId);
		user.setUserName(accounts);
		userInfoService.add(user);

		// 添加用户注册的默认角色
		if (roleDataCache != null) {
			List<String> ids = roleDataCache.getUserRegisterDefulatRoles();
			if (ids != null && ids.size() > 0) {
				for (String id : ids) {
					UserRoleEntity userRole = new UserRoleEntity();
					String urid = UUID.randomUUID().toString().replace("-", "");
					userRole.setId(urid);
					userRole.setRoleId(id);
					userRole.setUserId(userId);
					userRoleDao.add(userRole);
				}
			}
		}
		return true;
	}

	/**
	 * 设置密码
	 * 
	 * @return
	 */
	public boolean setPassword(String userid, String oldPwd, String newPwd) {
		if (userid == null || userid.equals("") || oldPwd == null || oldPwd.equals("") || newPwd == null
				|| newPwd.equals("")) {
			return false;
		}

		UserAuthenticationEntity entity = userAuthenticationDao.getEntity(userid);
		if (entity == null) {
			return false;
		}

		if (passwordEncoder != null) {
			oldPwd = passwordEncoder.encode(oldPwd);
			newPwd = passwordEncoder.encode(newPwd);
		}

		if (!entity.getPassword().equals(oldPwd)) {
			return false;
		}

		entity.setPassword(newPwd);
		userAuthenticationDao.update(entity);
		return true;
	}

	/**
	 * 密码验证
	 * 
	 * @return
	 */
	public boolean checkPassword(String accounts, String sPwd) {
		if (accounts == null || accounts.equals("") || sPwd == null || sPwd.equals("")) {
			return false;
		}

		UserAuthenticationEntity entity = userAuthenticationDao.getEntityByAccounts(accounts);
		if (entity == null) {
			return false;
		}

		if (passwordEncoder != null) {
			sPwd = passwordEncoder.encode(sPwd);
		}

		if (entity.getPassword().equals(sPwd)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 根据用户ID，获取所属角色，包括被委托角色
	 * 
	 * @param userid
	 * @return
	 */
	@Override
	public List<String> getUserRoles(String userid) {
		// 1.根据用户ID，查询用户角色表，获取用户关联的角色
		List<String> roles = roleDataProvide.getRoles(userid);
		if (roles == null) {
			roles = new ArrayList<String>();
		}
		// 2.根据用户ID，查询角色委托表，添加用户的角色
		List<String> entrustRoles = roleEntrustDataProvide.getRoles(userid);
		if (entrustRoles != null) {
			for (String r : entrustRoles) {
				if (!roles.contains(r)) {
					roles.add(r);
				}
			}
		}
		return roles;
	}

	/**
	 * 获取用户可访问的应用ID集
	 * 
	 * @param userid
	 *            唯一值
	 * @return
	 */
	public List<String> getUserService(String userid) {
		List<String> roles = getUserRoles(userid);
		return getRoleService(roles);
	}

	/**
	 * 添加用户可访问应用
	 * 
	 * @param userid
	 * @param service
	 */
	public boolean addUserService(String userid, String service) {
		if (roleDataCache == null) {
			return false;
		}
		List<String> roles = roleDataCache.getRegisterServiceRoles(service);
		if (roles == null) {
			return false;
		}
		for (String rid : roles) {
			roleService.addUserRole(userid, rid);
		}
		return true;
	}

	/**
	 * 移除用户可访问应用
	 * 
	 * @param userid
	 * @param service
	 */
	public boolean removeUserService(String userid, String service) {
		if (roleDataCache == null) {
			return false;
		}
		List<String> roles = roleDataCache.getRegisterServiceRoles(service);
		if (roles == null) {
			return false;
		}
		for (String rid : roles) {
			roleService.delUserRole(userid, rid);
		}
		return true;
	}

	/**
	 * 获取用户可访问的应用ID集
	 * 
	 * @param userid
	 *            唯一值
	 * @return
	 */
	public List<String> getRoleService(List<String> roles) {
		// 3.根据角色ID，查询角色与应用表，组建可用应用ID集
		return roleServiceDataProvide.getServiceIDs(roles);
	}

	/**
	 * 获取用户可访问菜单ID集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getUserMenus(String userid, String serviceId) {
		List<String> roles = getUserRoles(userid);
		return getRoleMenus(roles, serviceId);
	}

	/**
	 * 获取用户可访问菜单ID集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getRoleMenus(List<String> roles, String serviceId) {
		// 3.根据角色ID，查询角色与菜单表，组建可用菜单ID集
		List<String> menusIDs = roleMenusDataProvide.getMenusIDs(roles);
		// 4.根据菜单ID集，获取菜单集
		return menusJurisdictionDataProvide.getMenus(menusIDs, serviceId);
	}

	/**
	 * 获取用户可访问url地址集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getUserUrls(String userid, String serviceId) {
		List<String> roles = getUserRoles(userid);
		return getRoleUrls(roles, serviceId);
	}

	/**
	 * 获取用户可访问url地址集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getRoleUrls(List<String> roles, String serviceId) {
		// 3.根据角色ID，查询角色与菜单表，组建可用菜单ID集
		List<String> menusIDs = roleMenusDataProvide.getMenusIDs(roles);
		// 4.根据菜单ID集，获取菜单集
		return menusJurisdictionDataProvide.getUrls(menusIDs, serviceId);
	}

	/**
	 * 获取用户数据权限集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public Map<String, List<String>> getUserDatas(String userid, String serviceId) {
		List<String> roles = getUserRoles(userid);
		return getRoleDatas(roles, serviceId);
	}

	/**
	 * 获取用户数据权限集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public Map<String, List<String>> getRoleDatas(List<String> roles, String serviceId) {
		// 3.根据角色ID，查询角色与数据表，组建数据ID集
		List<String> dataIDs = roleDataDataProvide.getDataIDs(roles);
		// 4.根据数据ID集，获取数据集
		return dataJurisdictionDataProvide.getDatas(dataIDs, serviceId);
	}

	/**
	 * 获取用户可访问的地图图层集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public Map<String, List<String>> getUserMapLayers(String userid, String serviceId) {
		List<String> roles = getUserRoles(userid);
		return getRoleMapLayers(roles, serviceId);
	}

	/**
	 * 获取用户可访问的地图图层集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public Map<String, List<String>> getRoleMapLayers(List<String> roles, String serviceId) {
		// 3.根据角色ID，查询角色与数据表，组建数据ID集
		List<String> mapLayerIDs = roleMapLayersDataProvide.getMapLayerIDs(roles);
		// 4.根据数据ID集，获取数据集
		return mapLayersJurisdictionDataProvide.getMapLayers(mapLayerIDs, serviceId);
	}

	/**
	 * 获取用户可访问的地图范围集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getUserMapExtent(String userid, String serviceId) {
		List<String> roles = getUserRoles(userid);
		return getRoleMapExtent(roles, serviceId);
	}

	/**
	 * 获取用户可访问的地图范围集
	 * 
	 * @param userid
	 *            唯一值
	 * @param serviceId
	 * @return
	 */
	public List<String> getRoleMapExtent(List<String> roles, String serviceId) {
		// 3.根据角色ID，查询角色与数据表，组建数据ID集
		List<String> mapExtentIDs = roleMapExtentDataProvide.getMapExtentIDs(roles);
		// 4.根据数据ID集，获取数据集
		List<String> mapExtents = mapExtentJurisdictionDataProvide.getMapExtent(mapExtentIDs, serviceId);
		return mapExtents;
	}

	/**
	 * 获取系统可访问url地址集
	 * 
	 * @param sysid
	 *            系统ID值
	 * @param syspwd
	 *            系统访问码
	 * @return
	 */
	@Override
	public List<String> getSysUrls(String sysid, String syspwd) {
		return serviceJurisdictionDataProvide.getSysUrls(sysid, syspwd);
	}

	/**
	 * 通过系统id获取用户申请表系统信息（授权/取消授权）
	 */
	@Override
	public List<UserSysAuthoEntity> getUserSysAuthoEntitys(String sysId) {
		
		Map<String, Object> where = new HashMap<String, Object>();
		
		where.put("registerServiceId", sysId);
		
		List<UserSysAuthoEntity> userSysAuthoEntitys = userSysAuthoService.getEntitys(null, where, null, 10, 1);
		
		return userSysAuthoEntitys;
	}
}
